package Box2D.Dynamics
{
	import Box2D.Collision.b2AABB;
	import Box2D.Common.Math.b2Vec2;
	import Box2D.Common.b2Base;
	import Box2D.Common.b2Wrapper;
	import Box2D.Dynamics.Controllers.b2Controller;
	import Box2D.Dynamics.Controllers.b2ControllerDef;
	import Box2D.Dynamics.Joints.b2Joint;
	import Box2D.Dynamics.Joints.b2JointDef;
	
	import flash.utils.getDefinitionByName;
	
	import mx.core.mx_internal;

	public class b2World extends b2Wrapper
	{
		private var _debugDraw:b2DebugDraw
		private var _userData:*
		public function b2World(gravity:b2Vec2,doSleep:Boolean)
		{
			super()
			_wrapper = callDirect('b2World_new',this,gravity.wrapper,doSleep?1:0);			
		}
		public function Delete():void{
			call('b2World_delete');
			if(_debugDraw && _debugDraw.sprite)
				_debugDraw.sprite.graphics.clear()
		}
		public function SetDestructionListener(listener:b2DestructionListener):void{
			call('b2World_SetDestructionListener',listener.wrapper);
		}
		public function SetContactFilter(filter:b2ContactFilter):void{
			if(filter!=null)
				call('b2World_SetContactFilter',filter.wrapper);
			else
				call('b2World_SetContactFilter',null);			
		}
		public function GetContactFilter():b2ContactFilter{
			return call('b2World_GetContactFilter');
		}
		public function SetContactListener(listener:b2ContactListener):void{
			if(listener!=null)
				call('b2World_SetContactListener',listener.wrapper);
			else
				call('b2World_SetContactListener',null);
		}
		public function SetDebugDraw(debugDraw:b2DebugDraw):void{
			if(debugDraw!=null)
				call('b2World_SetDebugDraw',debugDraw.wrapper);
			else
				call('b2World_SetDebugDraw',null);
			_debugDraw = debugDraw;
		}
		public function CreateBody(def:b2BodyDef):b2Body{
			var body:b2Body = new b2Body();
			body.wrapper = call('b2World_CreateBody',def.wrapper,body);
			body.mx_internal::_world = this;
			return body;
		}
		public function DestroyBody(body:b2Body):void{
			call('b2World_DestroyBody',body.wrapper);
		}
		public function CreateJoint(def:b2JointDef):b2Joint{
			var joint:b2Joint = new def.cls();
			joint.wrapper = call('b2World_CreateJoint',def.wrapper,joint);
			return joint;
		}
		public function DestroyJoint(joint:b2Joint):void{
			call('b2World_DestroyJoint',joint.wrapper);
		}
		public function CreateController(def:b2ControllerDef):b2Controller{
			var controller:b2Controller = new def.cls();
			controller.wrapper = call('b2World_CreateController',def.wrapper,controller);
			controller.mx_internal::_world = this;
			return controller;
		}
		public function DestroyController(controller:b2Controller):void{
			call('b2World_DestroyController',controller.wrapper);
		}
		public function GetControllerList():b2Controller{
			return call('b2World_GetControllerList');
		}
		public function DrawDebugData():void{
			if(_debugDraw)
				_debugDraw.sprite.graphics.clear();
			call('b2World_DrawDebugData');
		}
		public function Step (timeStep:Number,velocityIterations:int,positionIterations:int):void{
			call('b2World_Step',timeStep,velocityIterations,positionIterations);
		}
		public function ClearForces():void{
			call('b2World_ClearForces');
		}
		public function QueryAABB(callback:b2QueryCallback,aabb:b2AABB):void{
			call('b2World_QueryAABB',callback.wrapper,aabb.wrapper);
		}
		public function RayCast(callback:b2RayCastCallback,point1:b2Vec2,point2:b2Vec2):void{
			call('b2World_RayCast',callback.wrapper,point1.wrapper,point2.wrapper);
		}
		public function GetBodyList():b2Body{
			return call('b2World_GetBodyList');
		}
		public function SetGravity(gravity:b2Vec2):void{
			call('b2World_SetGravity',gravity.wrapper);
		}
		public function GetGravity():b2Vec2{
			return new b2Vec2(0,0,call('b2World_GetGravity'));
		}
		public function SetUserData(value:*):void{_userData=value}
		public function GetUserData():*{return _userData}
	}
}